﻿using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;
using StackExchange.Redis;
using WebAPI.Application.Common.Interface;
using WebAPI.Domain.Entity;

namespace WebAPI.API.Controllers
{
    [Route("[controller]")]
    [ApiController]
    public class RedisController : ControllerBase
    {
        private StackExchange.Redis.IDatabase cache;
        private ConnectionMultiplexer connection;
        private readonly IConfiguration _configuration;
        private readonly IRepository<AppUser> _users;

        public RedisController(IConfiguration configuration, IRepository<AppUser> users)
        {
            _configuration = configuration;
            _users = users;

            // 拿到appsetting.json中的Redis配置，用于连接Redis
            string redisHost = _configuration["Redis:host"]; // 连接的url
            int redisPort = int.Parse(_configuration["Redis:port"]); // 端口

            // 连接配置
            var configurationOptions = new ConfigurationOptions
            {
                EndPoints =
                {
                    { redisHost, redisPort },
                },
                KeepAlive = 180, // 保存x秒的活动连接
                Password = _configuration["Redis:Password"], // 连接密码
                AllowAdmin = true
                //ConnectTimeout = 2000, //超时时间
            };
            connection = ConnectionMultiplexer.Connect(configurationOptions);
            cache = connection.GetDatabase();

        }

        [HttpGet]
        public dynamic GetAll()
        {
            var data = new
            {
                name = "张三"
            };
            return data;
        }

        [HttpPost]
        public dynamic SetCache()
        {

            var users = _users.Table.ToList();
            //var len = users.Count;
            //var user = users[0];

            string key = "users";
            if (cache.KeyExists(key))
            {
                cache.KeyDelete(key);
            }

            // 序列化工具
            var jsonOption = new JsonSerializerSettings()
            {
                ReferenceLoopHandling = ReferenceLoopHandling.Ignore
            };

            for (int i = 0; i < users.Count - 1; i++)
            {
                var redisStr = JsonConvert.SerializeObject(users[i],jsonOption);
            // 添加用户数据到redis
                cache.ListLeftPush(key, redisStr);
                // 
                cache.ListRightPush(key, redisStr);

            }
            //var jsonOption = new JsonSerializerSettings()
            //{
            //    ReferenceLoopHandling = ReferenceLoopHandling.Ignore
            //};
            //string strValue = JsonConvert.SerializeObject("王五", jsonOption);
            //cache.StringSet("name", strValue);

            var data = new
            {
                data = users
            };
            return data;
        }

        [HttpGet("/aaa")]
        public void ListTest()
        {

            string key = "list";
            var db = cache;
            if (db.KeyExists(key))
                db.KeyDelete(key);

            for (int i = 0; i < 10; i++)
            {
                // 将指定的值插入存储在key的列表的开头 ，相当于栈
                // 如果键不存在，则在执行推入操作之前将其创建为空列表
                db.ListLeftPush(key, "left_" + i.ToString());
                db.ListRightPush(key, "right_" + i.ToString());
            }
            Console.WriteLine("写入完成");
            var length = db.ListLength("list"); //读出list的长度
            Console.WriteLine($"list长度:{length}");

            //var str = db.ListLeftPop(key); //从顶部拿出数据
            ////Console.WriteLine(str);
            //str = db.ListRightPop(key); //从底部拿出数据
            //Console.WriteLine(str);
            // 设置key过期时间为1s
            db.KeyExpire("list", DateTime.Now.AddSeconds(1));

            // 程序等待1s
            Task.Delay(1*1000).Wait();
            var data = db.ListRange("list");
            Console.WriteLine(db.ListLength("list")); 
            Console.WriteLine(data);

            //返回存储在键列表中指定的元素。
            //偏移量start和stop是从零开始的索引，0是列表的第一个元素（列表的头），1是下一个元素，依此类推。
            //这些偏移也可以是负数，表示从列表。用于示例，-1是列表的最后一个元素，-2是倒数第二个元素，依此类推。
            //注意，如果您有一个从0到100的数字列表，LRANGE list 0 10将返回11个元素，也就是说，包含最右边的项。
            //var list = db.ListRange(key, 0, 4);
            //foreach (var item in list)
            //{
            //    Console.WriteLine(item);
            //}

            //str = db.ListRemove(key, "left_2"); //删除list中的单个数值
            //Console.WriteLine(str);

            //str = db.ListInsertAfter(key, list[3], "After"); //在某一位置后插入数据
            //Console.WriteLine(str);
            //str = db.ListInsertBefore(key, list[3], "Before"); //在某一位置前插入数据
            //Console.WriteLine(str);

            //删除list中的数据
            //while (db.ListLength(key) != 0)
            //{
            //    //从redis数据库弹出List里的数据
            //    //var str = db.ListRightPop(key);
            //    //Console.WriteLine(str);
            //}
        }

        //private string InitKey(string key)
        //{
        //    return $"{_configuration["Redis:preName"]}{key}";
        //}
    }
}
